﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;
using LaserTag.Infrastructure;
using LaserTag.Infrastructure.Events;
using LaserTag.Module.Vision.Views;
using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Presentation.Commands;

namespace LaserTag.Module.Vision.ViewModels
{
    public class VisionSetupViewModel : DependencyObject, 
                                        INotifyPropertyChanged, 
                                        IVisionSetupViewModel
    {

        private KeyValuePair<GraffitiEffect, string> m_selectedEffect;
        private ObservableCollection<KeyValuePair<GraffitiEffect, string>> m_graffitiEffects;

        public ICommand SetupCategorySelect { get; private set; }
        public ICommand ToggleShowGraffiti { get; private set; }
        private Screen m_selectedScreen;

        #region HeaderInfo

        public static readonly DependencyProperty HeaderInfoProperty =
            DependencyProperty.Register("HeaderInfo", typeof(string), typeof(VisionSetupViewModel),
                new FrameworkPropertyMetadata("Vision Setup"));

        private IEventAggregator m_eventAggregator;


        public string HeaderInfo
        {
            get { return (string)GetValue(HeaderInfoProperty); }
            set { SetValue(HeaderInfoProperty, value); }
        }

        #endregion

        private bool CanSetupCategorySelect(SetupCategory e)
        {
            return true;
        }

        private void OnSetupCategorySelect(SetupCategory e)
        {
            m_eventAggregator.GetEvent<SetupCategorySelected>().Publish(e);
        }

        private void OnToggleShowGraffiti(bool e)
        {
            m_eventAggregator.GetEvent<StartGraffitiEvent>().Publish(e);
        }

        private bool CanToggleShowGraffiti(bool e)
        {
            return m_selectedScreen != null;
        }

        public VisionSetupViewModel(IVisionSetupView view, IEventAggregator eventAggregator)
        {
            m_eventAggregator = eventAggregator;
            SetupCategorySelect = new DelegateCommand<SetupCategory>(OnSetupCategorySelect, CanSetupCategorySelect);
            ToggleShowGraffiti = new DelegateCommand<bool>(OnToggleShowGraffiti, CanToggleShowGraffiti);

            m_graffitiEffects = new ObservableCollection<KeyValuePair<GraffitiEffect, string>>
            {
                new KeyValuePair<GraffitiEffect, string>(GraffitiEffect.Fire, "Fire Effect "),
                new KeyValuePair<GraffitiEffect, string>(GraffitiEffect.Paint, "Paint Effect")
            };

            SelectedEffect = m_graffitiEffects[0];

            view.SetViewModel(this);
            View = view;
        }

        public Screen[] AvailableScreens
        {
            get
            {
                return Screen.AllScreens;
            }
        }

        public Screen SelectedScreen
        {
            get { return m_selectedScreen; }
            set
            {
                m_selectedScreen = value;
                InvokePropertyChanged("SelectedScreen");
                ((DelegateCommand<bool>) ToggleShowGraffiti).RaiseCanExecuteChanged();
                m_eventAggregator.GetEvent<GraffitiScreenChangedEvent>().Publish(value);
            }
        }

        public KeyValuePair<GraffitiEffect, string> SelectedEffect
        {
            get { return m_selectedEffect; }
            set
            {
                m_selectedEffect = value;
                m_eventAggregator.GetEvent<GraffitiEffectChangedEvent>().Publish(value.Key);
                InvokePropertyChanged("SelectedEffect");
            }
        }

        public ObservableCollection<KeyValuePair<GraffitiEffect, string>> GraffitiEffects
        {
            get { return m_graffitiEffects; }
            set
            {
                m_graffitiEffects = value;
                InvokePropertyChanged("GraffitiEffects");
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        private void InvokePropertyChanged(string propertyName)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            var changed = PropertyChanged;
            if (changed != null) changed(this, e);
        }

        #endregion

        #region IVisionSetupViewModel Members

        public IVisionSetupView View
        {
            get;
            private set;
        }

        #endregion
    }
}
